package com.thinkfit.jy.serialport;


import android.os.SystemClock;

import com.common.lib.bean.BasicResponse;
import com.common.lib.bean.SportSectionBean;
import com.common.lib.constant.EventBusEvent;
import com.common.lib.manager.DataManager;
import com.common.lib.network.HttpMethods;
import com.common.lib.utils.LogUtil;
import com.inuker.bluetooth.library.utils.ByteUtils;
import com.thinkfit.jy.utils.BluetoothOrder;
import com.thinkfit.jy.utils.DeviceTypeUtils;
import com.thinkfit.jy.utils.LogUtils;
import com.thinkfit.jy.utils.MotionDataUtils;
import com.thinkfit.jy.utils.SportsStatusBarViewUtils;
import com.thinkfit.jy.utils.Utils;

import org.greenrobot.eventbus.EventBus;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;

import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observer;

/**
 * 串口接口类（接上串口会自动判断串口连接）
 */
public class SerialPortManager {

    private static final String TAG = "SerialPortManager------------>";
    private static SerialPortManager mSerialPortManager;

    private FileInputStream mFileInputStream = null;
    private FileOutputStream mFileOutputStream = null;
    private SerialPort mSerialPort = null;
    private boolean mQuit = false;

    private final int UART_SERVICE_STATUS_VERIFY = 0;
    private final int UART_SERVICE_STATUS_NORMAL = 1;
    private int mStatus = UART_SERVICE_STATUS_VERIFY;

    private SportStatus mRunStatus = SportStatus.STOP;
    public SportStatus commandStatus = SportStatus.STOP;
    private long mStartTime;

    private LinkedList<Cmd> mCmdList;   //把指令放到一起，按顺序写入设备

    public static String mCurrentDeviceType = DeviceTypeUtils.SPINNING;

    private CurrentInfo mCurrentInfo;

    private int mIndex = 0;

    private ArrayList<SportSectionBean> mList;  //用来保存分段运动数据
    private SportType mSportType;  //1视频2语音3自由4实景

    public void setSportType(SportType sportType, int vid) {
        mSportType = sportType;
        mVid = vid;
        if (mSportType != SportType.FREE) {
            randUser();
        }
    }

    private final Object mLock = new Object();

    private SerialPortManager() {
        mStatus = UART_SERVICE_STATUS_VERIFY;
        if(mUartReceiveThread == null){
            mUartReceiveThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    while (!mQuit) {
                        switch (mStatus) {
                            case UART_SERVICE_STATUS_VERIFY:
                                SystemClock.sleep(20);
                                verify();
                                break;
                            case UART_SERVICE_STATUS_NORMAL:
                                SystemClock.sleep(200);
                                normal();
                                Cmd cmd = getCmd();
                                if (cmd == null) {  //有指令时先执行指令，没有指令时执行获取设备信息指令
                                    getDeviceStatus();
                                } else {
                                    sendMsg(cmd.bytes);
                                }
                                break;
                        }
                    }
                }
            });
        }
        mUartReceiveThread.start();
        mCmdList = new LinkedList<>();
        mList = new ArrayList<>();
        mSportType = null;

    }


    public static SerialPortManager getInstance() {
        if (mSerialPortManager == null) {
            synchronized (TAG) {
                if (mSerialPortManager == null) {
                    mSerialPortManager = new SerialPortManager();
                }
            }
        }
        return mSerialPortManager;
    }


    private boolean initUart(int baudrate) {
        try {
            mSerialPort = new SerialPort(new File("/dev/ttyMcuUart"), baudrate, 0);
        } catch (IOException e) {
            e.printStackTrace();
            LogUtil.LogE(e.toString());
            return false;
        }
        mFileInputStream = mSerialPort.getInputStream();
        mFileOutputStream = mSerialPort.getOutputStream();

        return true;
    }

    /**
     * 获取FCS（转换FCS）
     * @param buf
     * @param len
     * @return
     */
    public byte UartFCS(byte[] buf, int len) {
        byte i = 0, fcs = 0;
        for (i = 1; i < len; i++) {
            fcs ^= buf[i];
        }
        return fcs;
    }

    private int counter = 0;

    private void verify() {
        byte[] buf = new byte[32];
        int length = 0;

        buf[0] = 0x02;
        buf[1] = 0x50;
        buf[2] = 0x00;
        buf[3] = 0x50;
        buf[4] = 0x03;
        byte[] send = Arrays.copyOfRange(buf, 0, 5);
        switch (counter) {
            case 0:
                if (initUart(4800)) {
                    System.out.println("ddddddddddddddddddddddd  4800 "+bytesToHex(send));
                    try {
                        mFileOutputStream.write(buf, 0, 5);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                break;
            case 10:
                if (initUart(9600)) {
                    System.out.println("ddddddddddddddddddddddd  9600 "+bytesToHex(send));
                    try {
                        mFileOutputStream.write(buf, 0, 5);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                break;
            case 20:
                if (initUart(19200)) {
                    System.out.println("ddddddddddddddddddddddd  19200 "+bytesToHex(send));
                    try {
                        mFileOutputStream.write(buf, 0, 5);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                break;
            case 30:
                if (initUart(38400)) {
                    System.out.println("ddddddddddddddddddddddd  38400 "+bytesToHex(send));
                    try {
                        mFileOutputStream.write(buf, 0, 5);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                break;
            case 40:
                if (initUart(115200)) {
                    System.out.println("ddddddddddddddddddddddd  115200 "+bytesToHex(send));
                    try {
                        mFileOutputStream.write(buf, 0, 5);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                break;
        }
        if (++counter >= 50) {
            counter = 0;
        }
        try {
            length = mFileInputStream.read(buf, 0, 32);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("ddddddddddddddddddddddd  length : "+ length);
        if (length > 0 && length < 32) {
            byte[] tmp_buf;
//
//            System.arraycopy(buf, 0, tmp_buf, 0, length);
//            String response = bytesToHex(buf) + "";
//            LogUtil.LogE("response: "+response);

            if (length >= 4) {
                String response = bytesToHex(buf) + "";
                byte[] enen = Arrays.copyOfRange(buf, 0, length);
                System.out.println("ddddddddddddddddddddddd  enen : "+ bytesToHex(enen) + "");
                tmp_buf = new byte[length-2];
                System.arraycopy(enen, 0, tmp_buf, 0, length - 2);
                System.out.println("ddddddddddddddddddddddd  是否成功连接串口 : "+(UartFCS(tmp_buf, tmp_buf.length-1) == enen[length - 2]));

                if (UartFCS(tmp_buf, tmp_buf.length-1) == enen[length - 2]) {
                    mStatus = UART_SERVICE_STATUS_NORMAL;

                    String type = mCurrentDeviceType;
                    //       if (response.startsWith("025000")) {
                    MotionDataUtils.getInstance().motionDataResponse(enen);

//                    initInput(enen);

//                    if (response.startsWith("025000")) {
//                        mCurrentDeviceType = DeviceType.RUNNING_MACHINE;
//                        System.out.println("ddddddddddddddddddddddd  mCurrentDeviceType : 跑步机");
//                    } else if (response.startsWith("020660")) {
//                        mCurrentDeviceType = DeviceType.CAR_WATCH;
//                        System.out.println("ddddddddddddddddddddddd  mCurrentDeviceType : 车机");
//                    }
                    if (!type.equals(mCurrentDeviceType)) {
                        HttpMethods.Companion.getInstance().setSType(DeviceTypeUtils.getDeviceType() == 2 ?
                                "2" : "1");
                        HashMap<String, Object> map = new HashMap<>();
                        map.put(EventBusEvent.RESTART_APP, "");
                        EventBus.getDefault().post(map);
                    }
                    if (DeviceTypeUtils.getDeviceType() == 2) {  //跑步机才调用
                        addCmd(getSpeedCmd());
                        addCmd(getSlopCmd());
                    }
//                        else {
//                            getDeviceStatus();
//                        }
                }
            }
        }
    }

    public void initInput(byte[] enen){
        System.out.println(TAG+" ddddddddddddddddddddddd enen : "+ ByteUtils.byteToString(enen)+"  enen.length"+enen.length);
        if(enen == null || enen.length <= 4 ){
            return;
        }
        String instruct1 = Long.toString(enen[1] & 0xff, 16);
        String instruct2 = Long.toString(enen[2] & 0xff, 16);//转换会把前面的"0"给略掉，需要可以用StringBuffer拼上
        System.out.println(TAG+" ddddddddddddddddddddddd value[1] : "+instruct1+"   value[2] :"+instruct2);

        if(instruct1.equals("41")&& instruct2.equals("2")){
            //设备参数
            BluetoothOrder.getInstance().equipmentInfo(enen);

        }else if(instruct1.equals("50")&& instruct2.equals("0")){
            //获取设备品牌
            String str = Long.toString(enen[4] & 0xff, 16);
//            if(DeviceTypeUtils.TREADMILL.equals(str) || DeviceTypeUtils.WALKING_TREADMILL.equals(str)){
//                System.out.println(TAG+" ddddddddddddddddddddddd enen :  跑步机");
//                mCurrentDeviceType = DeviceTypeUtils.TREADMILL;
//            }else {
//                System.out.println(TAG+" ddddddddddddddddddddddd enen :  车机");
//                mCurrentDeviceType = DeviceType.CAR_WATCH;
//            }
//            BluetoothOrder.getInstance().getBrandInfo(enen);

        }else if(instruct1.equals("42")){
            //获取设备状态
            BluetoothOrder.getInstance().getEquipmentState(enen);
        }else if(instruct1.equals("43")&&instruct2.equals("1")){
            //获取运动数据
            BluetoothOrder.getInstance().getSportsData(enen);
        }else if(instruct1.equals("44")&&instruct2.equals("1")){
            //准备就绪
            System.out.println("ddddddddddddddddddddddd   蓝牙通知界面准备就绪状态  ");
            if(mRunStatus == SportStatus.START){
                return;
            }
            mRunStatus = SportStatus.START;
            int countdown = BluetoothOrder.getInstance().formatHexInt(Long.toString(enen[3] & 0xff, 16));
            System.out.println(TAG+" countdown : "+countdown);
            if (countdown > 0) {
                HashMap<String, Object> map = new HashMap<>();
                map.put(EventBusEvent.START_RUN, countdown);
                EventBus.getDefault().post(map);
            }else {
                System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaa    7777");
                Cmd cmd = new Cmd();
                cmd.bytes = BluetoothOrder.EQUIPMENT_START_OR_CONTINUE;
                addCmd(cmd);
//                sendMsg(BluetoothOrder.EQUIPMENT_START_OR_CONTINUE);
            }
        }else if(instruct1.equals("44")&&instruct2.equals("2")){
            //设备开始或继续
            System.out.println("ddddddddddddddddddddddd   蓝牙通知界面刷新开始状态  "+(mRunStatus == SportStatus.RUNNING));
            if(mRunStatus == SportStatus.RUNNING){
                return;
            }
            mRunStatus = SportStatus.RUNNING;
//            getEquipmentState();
//                        BluetoothOrder.getInstance().getEquipmentState();//获取设备状态
//            Observable.timer(500, TimeUnit.MILLISECONDS)
//                    .subscribe(new Consumer<Long>() {
//                        @Override
//                        public void accept(Long aLong) throws Exception {
//                             getSportsInfo();//获取运动数据
//                        }
//                    });

            System.out.println("ddddddddddddddddddddddd   蓝牙通知界面刷新开始状态");
            HashMap<String, Object> map = new HashMap<>();
            map.put(EventBusEvent.RUNNING, 0);
            EventBus.getDefault().post(map);

        }else if(instruct1.equals("44")&&instruct2.equals("3")){
            //设备暂停
            if(mRunStatus == SportStatus.PAUSE){
                return;
            }
            mRunStatus = SportStatus.PAUSE;
            System.out.println("ddddddddddddddddddddddd   串口通知界面刷新暂停状态");
            HashMap<String, Object> map = new HashMap<>();
            map.put(EventBusEvent.PAUSE_RUN, 0);
            EventBus.getDefault().post(map);
        }else if(instruct1.equals("44")&&instruct2.equals("4")){
            //设备停止
            if(mRunStatus == SportStatus.STOP){
                return;
            }
            mRunStatus = SportStatus.STOP;
//            closeThread();
            System.out.println("ddddddddddddddddddddddd   串口通知界面刷新停止状态");
            HashMap<String, Object> map = new HashMap<>();
            map.put(EventBusEvent.STOP_RUN, 0);
            EventBus.getDefault().post(map);
        }else if(instruct1.equals("44")&&instruct2.equals("5")){
            //设置阻力和坡度

        }else if(instruct1.equals("50")&&instruct2.equals("2")){
            //获取跑步机速度参数
            BluetoothOrder.getInstance().setTreadmillSpeed(enen);

        }else if(instruct1.equals("50")&&instruct2.equals("3")){
            //获取跑步机坡度参数
            BluetoothOrder.getInstance().setTreadmillSlop(enen);

        }else if(instruct1.equals("50")&&instruct2.equals("4")){
            //获取跑步机累计⾥程
            BluetoothOrder.getInstance().setTreadmillMileage(enen);

        }else if(instruct1.equals("51")){
            System.out.println("aaaaaaaaaaaaaaaaaaaaaaAA   commandStatus   : "+commandStatus);
            System.out.println("aaaaaaaaaaaaaaaaaaaaaaAA   mRunStatus   : "+mRunStatus);
            if(commandStatus != null && commandStatus != mRunStatus){
                if(commandStatus == SportStatus.START||commandStatus == SportStatus.RUNNING){
                    startRun();
                }else if(commandStatus == SportStatus.STOP){
                    stopRun();
                }else if(commandStatus == SportStatus.PAUSE){
                    pauseRun();
                }
                return;
            }
            commandStatus = null;
            //获取跑步机状态
            BluetoothOrder.getInstance().getTreadmillInfo(enen);

        }else if(instruct1.equals("53")&&instruct2.equals("1")){
            //跑步机准备就绪
            System.out.println("ddddddddddddddddddddddd   串口通知跑步机准备就绪状态  ");
            if(mRunStatus == SportStatus.START){
                return;
            }
            mRunStatus = SportStatus.START;
            BluetoothOrder.getInstance().setRunStatus(SportStatus.START);
            int countdown = BluetoothOrder.getInstance().formatHexInt(Long.toString(enen[3] & 0xff, 16));
            System.out.println(TAG+" countdown : "+countdown);
            if (countdown > 0) {
                HashMap<String, Object> map = new HashMap<>();
                map.put(EventBusEvent.START_RUN, countdown);
                EventBus.getDefault().post(map);
            }else {
                HashMap<String, Object> map = new HashMap<>();
                map.put(EventBusEvent.RUNNING, 0);
                EventBus.getDefault().post(map);

//                            BluetoothOrder.getInstance().getTreadmillState();
            }

        }else if(instruct1.equals("53")&&instruct2.equals("2")){
            //跑步机设置速度和坡度指令
            BluetoothOrder.getInstance().treadmillSpeedAndSlope(enen);


        }else if(instruct1.equals("53")&&instruct2.equals("3")){
            //跑步机停止指令
            if(mRunStatus == SportStatus.STOP){
                return;
            }
            mRunStatus = SportStatus.STOP;
            BluetoothOrder.getInstance().setRunStatus(SportStatus.STOP);
            System.out.println("ddddddddddddddddddddddd   跑步机串口通知界面刷新停止状态");
            HashMap<String, Object> map = new HashMap<>();
            map.put(EventBusEvent.STOP_RUN, 0);
            EventBus.getDefault().post(map);
        }else if(instruct1.equals("53")&&instruct2.equals("9")){
            //跑步机开始指令
            System.out.println("ddddddddddddddddddddddd   串口通知跑步机刷新开始状态  "+(mRunStatus == SportStatus.RUNNING)+"  mRunStatus  : "+mRunStatus.toString());
            if(mRunStatus == SportStatus.RUNNING){
                return;
            }
            mRunStatus = SportStatus.RUNNING;
            BluetoothOrder.getInstance().setRunStatus(SportStatus.RUNNING);
            System.out.println("ddddddddddddddddddddddd   串口通知界面刷新开始状态");
            HashMap<String, Object> map = new HashMap<>();
            map.put(EventBusEvent.RUNNING, 0);
            EventBus.getDefault().post(map);

        }else if(instruct1.equals("53") && instruct2.equals("a")){
            //跑步机暂停指令
            if(mRunStatus == SportStatus.PAUSE){
                return;
            }
            mRunStatus = SportStatus.PAUSE;
//            BluetoothOrder.getInstance().setRunStatus(SportStatus.PAUSE);
            System.out.println("ddddddddddddddddddddddd   串口通知界面刷新暂停状态");
            HashMap<String, Object> map = new HashMap<>();
            map.put(EventBusEvent.PAUSE_RUN, 0);
            EventBus.getDefault().post(map);
        }
    }

    public boolean isConnected() {
        return mStatus == UART_SERVICE_STATUS_NORMAL;
    }

    private void normal() {
        byte[] buf = new byte[32];
        int length = 0;
        try {
            length = mFileInputStream.read(buf, 0, 32);
        } catch (IOException e) {
            e.printStackTrace();
        }
//        System.out.println("ddddddddddddddddddddddd   normal   length: " + length);
        if (length > 0 && length < 32) {
            byte[] tmp_buf = new byte[length];
            System.arraycopy(buf, 0, tmp_buf, 0, length);
            String response = bytesToHex(buf) + "";
//            System.out.println("ddddddddddddddddddddddd    normal   response: " + response);
            MotionDataUtils.getInstance().motionDataResponse(tmp_buf);

//            initInput(tmp_buf);

        }
    }


    public boolean isRun() {
        return mRunStatus == SportStatus.START || mRunStatus == SportStatus.RUNNING ;
    }

    public boolean isPause() {
        return mRunStatus == SportStatus.PAUSE;
    }
    public boolean isStop() {
        return mRunStatus == SportStatus.STOP;
    }

    public void setRunStatus(SportStatus status){
        mRunStatus = status;
    }

    private String bytesToHex(byte[] bytes) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() < 2) {
                sb.append(0);
            }
            sb.append(hex);
        }
        return sb.toString();
    }

    public CurrentInfo getCurrentInfo() {
        if (mCurrentInfo == null) {
            mCurrentInfo = new CurrentInfo();
        }
        return mCurrentInfo;
    }

    public void closeCurrentInfo(){
        if (mCurrentInfo != null){
            mCurrentInfo = null;
        }
    }

    // 验证有没有连接上
    private Thread mUartReceiveThread;

    public void closeThread(){
        if(mUartReceiveThread != null){
            if(mUartReceiveThread.isAlive()){
                mStatus = -1;
            }
        }

    }

    public void addCmd(Cmd cmd) {
        synchronized (mLock) {
            for (Cmd c : mCmdList) {
                if (c.cmd == cmd.cmd) {
                    return;
                }
            }
            mCmdList.addLast(cmd);
        }
    }

    private Cmd getCmd() {
        synchronized (mLock) {
            if (!mCmdList.isEmpty()) {
                return mCmdList.removeLast();
            }
            return null;
        }
    }


    public void sendMsg(byte[] buf) {
        if (isConnected() && mFileOutputStream != null) {
            try {
                LogUtils.getInstance().l(LogUtils.MOTION_DATA, "ddddddddddddddddddddddd    sendMsg111 :  "+bytesToHex(buf));
                mFileOutputStream.write(buf);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    public void getDeviceStatus() {  //获取设备状态  速度那些
        byte[] bytes = null;
        if (MotionDataUtils.mCurrentDeviceType.equals(DeviceTypeUtils.TREADMILL)) {
//            bytes = new byte[]{0x02, 0x51, 0x51, 0x03};
            bytes = BluetoothOrder.TREADMILL_GET_EQUIPMENT_INFO;
        } else { //获取信息有两条指令，得轮流发
            if (mIndex % 2 == 0) {
                bytes = BluetoothOrder.EQUIPMENT_GET_EQUIPMENT_INFO;
            } else {
                bytes = BluetoothOrder.EQUIPMENT_GET_SPORTS_INFO;
            }
            ++mIndex;
            if (mIndex >= 1000) {
                mIndex = 0;
            }
        }
        if (bytes != null) {
            sendMsg(bytes);
        }
    }

    private Cmd getSpeedCmd() {
        Cmd cmd = new Cmd();
        cmd.cmd = 1;
        if (MotionDataUtils.mCurrentDeviceType.equals(DeviceTypeUtils.TREADMILL)) {
//            cmd.bytes = new byte[]{0x02, 0x50, 0x02, 0x52, 0x03};
            cmd.bytes = BluetoothOrder.TREADMILL_GET_SPEED;
        }
        return cmd;
    }

    private Cmd getSlopCmd() {
        Cmd cmd = new Cmd();
        cmd.cmd = 2;
//        cmd.bytes = new byte[]{0x02, 0x50, 0x03, 0x53, 0x03};
        cmd.bytes = BluetoothOrder.TREADMILL_GET_SLOP;
        return cmd;
    }
    // 启动连接
    public void startRun() {
        Cmd cmd = new Cmd();
        cmd.cmd = 3;
        if (MotionDataUtils.mCurrentDeviceType.equals(DeviceTypeUtils.TREADMILL)) {
            System.out.println("ddddddddddddddddddddddd  RUNNING_MACHINE ");
//            cmd.bytes = new byte[]{0x02, 0x53, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
//                    handData("53010000000000000000"), 0x03};
//            cmd.bytes = new byte[]{0x02,0x53,0x01,0x50,0x03};
            if(isPause()){
                cmd.bytes = BluetoothOrder.TREADMILL_START;
            }else {
                cmd.bytes = BluetoothOrder.TREADMILL_READY;
            }
            mStartTime = System.currentTimeMillis();
            commandStatus = SportStatus.RUNNING;
//            HashMap<String, Object> map = new HashMap<>();
//            map.put(EventBusEvent.START_RUN, 0);
//            EventBus.getDefault().post(map);
        } else {
            System.out.println("ddddddddddddddddddddddd  CAR_WATCH ");
//            cmd.bytes = new byte[]{0x02, 0x44, 0x01, 0x45, 0x03};
            cmd.bytes = BluetoothOrder.EQUIPMENT_READY;
//            cmd.bytes = new byte[]{0x02, 0x07, 0x61, 0x39, 0x01, 0x00, 0x00, 0x00, 0x00, handData("0761390100000000"), 0x03};
            mRunStatus = SportStatus.START;
            mStartTime = System.currentTimeMillis();
//            HashMap<String, Object> map = new HashMap<>();
//            map.put(EventBusEvent.START_RUN, 0);
//            EventBus.getDefault().post(map);
            commandStatus = SportStatus.START;
        }

        addCmd(cmd);
    }

    //停止连接
    public void stopRun() {
        Cmd cmd = new Cmd();
        cmd.cmd = 4;
        if (MotionDataUtils.mCurrentDeviceType.equals(DeviceTypeUtils.TREADMILL)) {
//            cmd.bytes = new byte[]{0x02, 0x53, 0x03, handData("5303"), 0x03};
            cmd.bytes = BluetoothOrder.TREADMILL_STOP;
            mRunStatus = SportStatus.STOP;
        } else  {
            cmd.bytes = BluetoothOrder.EQUIPMENT_STOP;
//            cmd.bytes = new byte[]{0x02, 0x07, 0x61, 0x39, 0x01, 0x00, 0x00, 0x00, 0x00, handData("0761390100000000"), 0x03};
            mStartTime = 0;
//            HashMap<String, Object> map = new HashMap<>();
//            map.put(EventBusEvent.STOP_RUN, 0);
//            EventBus.getDefault().post(map);

            getCurrentInfo().lastCount = 0;
            getCurrentInfo().count = 0;
            getCurrentInfo().time = 0;
            getCurrentInfo().rpm = 0;
            getCurrentInfo().resistance = 0;
            SportCalculateManager.getInstance().resetSportData();
        }
        commandStatus = SportStatus.STOP;
        mCmdList.clear();
        addCmd(cmd);

    }

    public void setSpeedSlop(int speed, int slop) {
        Cmd cmd = new Cmd();
        cmd.cmd = 5;
//        cmd.bytes = new byte[]{0x02, 0x53, 0x02, (byte) speed, (byte) slop,
//                handData("5302" + getNewHex(speed) + getNewHex(slop)), 0x03};
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("02");
        stringBuffer.append("53");
        stringBuffer.append("02");
        stringBuffer.append(BluetoothOrder.getInstance().integerToHexString(speed));
        stringBuffer.append(BluetoothOrder.getInstance().integerToHexString(slop));
        stringBuffer.append("00");
        stringBuffer.append("03");
        byte[] bytes = BluetoothOrder.getInstance().hexToByteArray(stringBuffer.toString());
        byte b = SerialPortManager.getInstance().UartFCS(bytes, bytes.length-2);
        bytes[5] = b;
        cmd.bytes = bytes;
        addCmd(cmd);
    }


    public void setResistanceSlop(int resistance, int slop) {
        Cmd cmd = new Cmd();
        cmd.cmd = 5;
//        cmd.bytes = new byte[]{0x02, 0x44, 0x05, (byte) resistance, (byte) slop,
//                handData("4405" + getNewHex(resistance) + getNewHex(slop)), 0x03};
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("02");
        stringBuffer.append("44");
        stringBuffer.append("05");
        stringBuffer.append(BluetoothOrder.getInstance().integerToHexString(resistance));
        stringBuffer.append(BluetoothOrder.getInstance().integerToHexString(slop));
        stringBuffer.append("00");
        stringBuffer.append("03");
        byte[] bytes = BluetoothOrder.getInstance().hexToByteArray(stringBuffer.toString());
        byte b = SerialPortManager.getInstance().UartFCS(bytes, bytes.length-2);
        bytes[5] = b;
        System.out.println(TAG+" ddddddddddddddddddddddd  "+Long.toString(b & 0xff, 16)+"   "+ByteUtils.byteToString(bytes));

        cmd.bytes = bytes;
//        cmd.bytes = new byte[]{0x02, 0x07, 0x61, (byte) ((resistance - 1) * 8 + 1), 0x01, 0x00, 0x00, 0x00, 0x00, handData("0761" + getNewHex((resistance - 1) * 8 + 1) + "0100000000"), 0x03};
        //Log.e("aaaaaaaaaa", "resistance: " + ((byte) (resistance * 8 + 7)));
        // cmd.bytes = new byte[]{0x02, 0x07, 0x61, (byte) (resistance * 8 + 7), 0x01, 0x00, 0x00, 0x00, 0x00, handData("0761" + getNewHex(resistance * 8 + 7) + "0100000000"), 0x03};

        addCmd(cmd);
    }


    private String getNewHex(int value) {
        String hex = Integer.toHexString(value);
        if (hex.length() == 1) {
            return "0" + hex;
        }
        return hex;
    }


    public void reStartRun() {
        mCmdList.clear();
        Cmd cmd = new Cmd();
        cmd.bytes = BluetoothOrder.TREADMILL_START;
        commandStatus = SportStatus.RUNNING;
//        sendMsg(bytes);
        addCmd(cmd);
    }

    public void pauseRun() {
//        byte[] bytes = new byte[]{0x02, 0x53, 0x0a, handData("530a"), 0x03};
        Cmd cmd = new Cmd();
        byte[] bytes;
        if(MotionDataUtils.mCurrentDeviceType.equals(DeviceTypeUtils.TREADMILL)){
            bytes = BluetoothOrder.TREADMILL_PAUSE;
        }else {
            bytes = BluetoothOrder.EQUIPMENT_PAUSE;
        }
        cmd.bytes = bytes;
        mStartTime = 0;
        commandStatus = SportStatus.PAUSE;
//        HashMap<String, Object> map = new HashMap<>();
//        map.put(EventBusEvent.PAUSE_RUN, 0);
//        EventBus.getDefault().post(map);
//        sendMsg(bytes);
        mCmdList.clear();
        addCmd(cmd);
    }

    public SportStatus getCommandStatus(){
        return commandStatus;
    }

    private byte handData(String text) {   //异或处理
        int length = text.length();
        int result = Integer.parseInt(text.substring(0, 2), 16);
        for (int i = 2; i < length; i = i + 2) {
            result = result ^ Integer.parseInt(text.substring(i, i + 2), 16);
        }
        return (byte) result;
    }

    public static class Cmd {
        public int cmd;
        public byte[] bytes;
    }

    // private int

    public static class CurrentInfo {
        public int speed;  //当前速度
        public int slop; //当前跑步机是坡度 车表是阻力
        public int time; //当前时间
        public int distance; //当前距离
        public int kcal; //当前热量
        public int steps; //当前步数
        public int heart; //当前心率

        public int resistance;//阻力
        public int rpm;//RPM
        public int power;//功率
        public int count;//计数

        public int lastCount;//记录上一次返回的count，如果不同count+1
        public boolean isCountChange;  //记录次数是否变化

        @Override
        public String toString() {
            return "CurrentInfo{" +
                    "speed=" + speed +
                    ", slop=" + slop +
                    ", time=" + time +
                    ", distance=" + distance +
                    ", kcal=" + kcal +
                    ", steps=" + steps +
                    ", heart=" + heart +
                    ", resistance=" + resistance +
                    ", rpm=" + rpm +
                    ", power=" + power +
                    ", count=" + count +
                    ", lastCount=" + lastCount +
                    ", isCountChange=" + isCountChange +
                    '}';
        }
    }

    private int mCount;//累加次数，用来算平均
    private int mTotalResistance;  //一分钟内相加阻力总和
    private int mTotalSpeed;  //一分钟内相加速度总和
    private int mLastMinPower;  ///截止上一分钟内总功率
    private int mTotalHeart;  //一分钟内相加心率总和

    private int mTotalDistance;
    private int mMaxHeart;

    private int mLastTime = -1;//上次时间，如果两次时间相等，就不要处理
    private int mRid;
    private int mScore;
    private int mMateId;
    private boolean mIsRandomUser;

    private int mSportCount;  //划桨次数
    private int mTotalKcal;//
    private int mLastUploadTime = 0;

    private int mVid;

    private void addSportSection() {
        if (getCurrentInfo().time <= 0 || mLastTime == getCurrentInfo().time) {
            return;
        }
        mLastTime = getCurrentInfo().time;
        mSportCount = getCurrentInfo().count;
        mTotalKcal = getCurrentInfo().kcal;
        int min = getCurrentInfo().time / 60 + 1;
        SportSectionBean bean = null;
        for (SportSectionBean b : mList) {
            if (b.getMin() == min) {
                bean = b;
                break;
            }
        }
        if (bean == null) {
            mCount = 0;
            mTotalResistance = 0;
            mTotalHeart = 0;
            mTotalSpeed = 0;
            mLastMinPower = getCurrentInfo().power;
            bean = new SportSectionBean();
            mList.add(bean);
        }
        ++mCount;
        mTotalHeart += getCurrentInfo().heart;
        mTotalResistance += getCurrentInfo().resistance;
        mTotalSpeed += getCurrentInfo().speed;
        bean.setMin(min);
        bean.setDrag(mTotalResistance / mCount);
        bean.setReta(mTotalHeart / mCount);
        bean.setSpeed(Utils.getNewFloat(mTotalSpeed / mCount));
        bean.setWatts(Utils.getNewFloat((getCurrentInfo().power - mLastMinPower) * 0.1f));

        mTotalDistance = getCurrentInfo().distance;
        if (getCurrentInfo().heart > mMaxHeart) {
            mMaxHeart = getCurrentInfo().heart;
        }

        if (mMateId <= 0) {
            randUser();
        }

        if (mLastTime - mLastUploadTime >= 10 && mSportType != SportType.FREE) {
            uploadSportInfo(false);
        }
    }

    private void reset() {
        mLastTime = 0;
        mList.clear();
        mMaxHeart = 0;
        mRid = 0;
        mLastUploadTime = 0;
        mScore = 0;
        mMateId = 0;
        mIsRandomUser = false;
    }

    private void uploadSportInfo(boolean isEnd) {
        if (!DataManager.Companion.getInstance().isLogin() || mLastTime < 10 || mSportType == null) {  //自由运动少于10秒不传
            return;
        }
        Observer observer = new Observer<BasicResponse<Object>>() {

            @Override
            public void onSubscribe(io.reactivex.rxjava3.disposables.@NonNull Disposable d) {

            }

            @Override
            public void onNext(BasicResponse<Object> bean) {
                if (bean.isSuccess()) {
                    mRid = bean.getRid();
                    LogUtil.LogE("mRid: " + mRid);
                }
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        };
        if (mSportType == SportType.FREE) {
            HttpMethods.Companion.getInstance().runUploadSportInfo(
                    DataManager.Companion.getInstance().getMyInfo().getUid(),
                    mRid, mSportType.getValue(), Utils.getNewFloat2(mTotalDistance / 1000f),
                    Utils.getNewFloat(mLastMinPower * 0.1f), String.valueOf(mSportCount * 60 / mLastTime), String.valueOf(mMaxHeart),
                    Utils.getNewFloat(mLastMinPower * 0.1f), Utils.getNewFloat(mTotalKcal * 0.1f), mLastTime,
                    DataManager.Companion.getInstance().getGson().toJson(mList), isEnd ? 1 : 0,
                    observer);
        } else {
            mLastUploadTime = mLastTime;
            if (mMateId <= 0) {
                randUser();
                return;
            }
            HttpMethods.Companion.getInstance().uploadSportInfo(
                    DataManager.Companion.getInstance().getMyInfo().getUid(),
                    mRid, mVid, mSportType.getValue(), mScore, mMateId, Utils.getNewFloat2(mTotalDistance / 1000f),
                    Utils.getNewFloat(mLastMinPower * 0.1f), String.valueOf(mSportCount * 60 / mLastTime), String.valueOf(mMaxHeart),
                    Utils.getNewFloat(mLastMinPower * 0.1f), Utils.getNewFloat(mTotalKcal * 0.1f), mLastTime,
                    DataManager.Companion.getInstance().getGson().toJson(mList), isEnd ? 1 : 0,
                    observer);
        }

    }

    private void randUser() {
        if (!DataManager.Companion.getInstance().isLogin() || mIsRandomUser || mSportType == null || mSportType == SportType.FREE) {
            return;
        }
        mIsRandomUser = true;
        HttpMethods.Companion.getInstance().randomUser(
                DataManager.Companion.getInstance().getMyInfo().getUid(),
                mVid, mSportType.getValue(),
                new Observer<BasicResponse<Object>>() {

                    @Override
                    public void onSubscribe(io.reactivex.rxjava3.disposables.@NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(BasicResponse<Object> bean) {
                        if (bean.isSuccess()) {
                            mMateId = bean.getMateid();
                            LogUtil.LogE("mMateId: " + mMateId);
                        }
                        mIsRandomUser = false;
                    }

                    @Override
                    public void onError(Throwable e) {
                        mIsRandomUser = false;
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

}
